'use strict';

const uniConfig = require('uni-config-center');
const uidConfig = uniConfig({
	pluginId: 'uni-id'
});

const uidObj = require('uni-id');
const {
	Controller
} = require('uni-cloud-router');

module.exports = class MoneyController extends Controller {
	
	// 零钱中心
	async data() {
		let response = {
			code: 1,
			msg: '',
			datas: {}
		};
		
		let uid = '';
		let uname = '';
		const nowdate = Date.now();
		
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const memberRes = await this.db.collection('usemall-member').doc(uid)
			.field({
				member_amount: true,
				profit_amount: true,
				unprofit_amount: true
			})
			.get();
		const [memberData] = memberRes.data;
		
		const configRes = await this.db.collection('usemall-wallet-parameter').get();
		const [config] = configRes.data;
		
		response.datas = memberData;
		response.datas.config = config;
		response.code = 0;
		return response;
	}
	
	// 提现明细
	async cashoutRecord() {
		let response = {
			code: 1,
			msg: '',
			datas: {}
		};
		
		const { state } = this.ctx.data;
		
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		let whereObj = { uid: uid };
		if (state) {
			whereObj.state = state;
		}
		
		const cashoutRes = await this.db.collection('usemall-member-cashout').where(whereObj).orderBy("create_time", "desc").get();
		
		response.datas = cashoutRes;
		response.code = 0;
	
		return response;
	}
	
	// 申请提现
	async cashout() {
		let response = {
			code: 1,
		};
		
		let uid = '';
		let uname = '';
		const nowdate = Date.now();
		
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		// 申请提现金额（单位分）
		this.ctx.data.cashout_amount = parseInt(this.ctx.data.cashout_amount);
		
		const {
			cashout_amount,
			cashout_way,
			cashout_way_id
		} = this.ctx.data;
		
		if (cashout_amount <= 0) {
			this.throw('提现金额需大于0');
		}
		
		// 最低 0.3元
		// 最高 2000元
		const min_cashout = 0.3 * 100;
		const max_cashout = 2000 * 100;
		
		if (!(cashout_amount >= min_cashout && cashout_amount <= max_cashout)) {
			this.throw(`提现金额范围：${min_cashout / 100}~${max_cashout / 100}`);
		}
		
		const userRes = await this.db.collection('usemall-member').doc(uid).field({
			member_amount: true,
			member_truename: true
		}).get();
		if (!(userRes && userRes.data.length === 1)) {
			response.msg = '请重新登录';
			return response;
		}
		const [userData] = userRes.data;
		
		if(cashout_amount > userData.member_amount) {
			this.throw('提现金额大于可提现金额' + userData.member_amount / 100 + '元');
		}
		
		const walletConfigRes = await this.db.collection('usemall-wallet-parameter').field({
				check_name: true,
				service_charge: true,
				pattern: true
			})
			.limit(1)
			.get();
		const [walletConfig] = walletConfigRes.data;
		if (walletConfig && walletConfig.check_name == 'FORCE_CHECK' && !userData.member_truename) {
			this.throw(`提现需填写真实姓名，请先完善个人信息`);
		} 
		
		const cashoutRes = await this.db.collection('usemall-member-cashout').add({
			uid: uid, 
			cashout_amount: cashout_amount,
			cashout_way: cashout_way,
			cashout_way_id: cashout_way_id,
			state: '待审核',
			create_time: nowdate,
			create_uid: uid,
			create_uname: uname,
			version: 1,
			is_delete: 0,
			ip: this.ctx.context.CLIENTIP
		});
		
		try {
			// 消息通知
			// 不需要 await，只需发送请求即可
			const messageNotifyUrl = `${uidConfig.config('message-notify.url')}/302`;
			if (messageNotifyUrl.indexOf('http') === 0) {
				uniCloud.httpclient.request(messageNotifyUrl, {
					method: 'post',
					headers: {
						'message-notify-key': uidConfig.config('message-notify.key')
					},
					data: {
						id: cashoutRes.id,
						scene: 302,
						title: `申请零钱提现`,
						uname: `${uname}`,
						money: `￥${(cashout_amount / 100).toFixed(2)}`,
						way: `${cashout_way}`,
					},
					timeout: 30 * 1000,
					contentType: 'json',
					dataType: 'json'
				});
			}
		} catch(e) {
			console.log('message-notify err', e);
		}
		
		await this.db.collection('usemall-member').doc(uid).update({
			unprofit_amount: this.db.command.inc(cashout_amount),
			member_amount: this.db.command.inc(-cashout_amount),
			last_modify_time: nowdate,
			last_modify_uid: uid
		});
		
		response.code = 0;
		response.msg = '提交成功';
		
		return response;
	}
	
	// 零钱日志
	async log() {
		let response = {
			code: 1,
			msg: '',
			datas: {}
		};
		
		const { state } = this.ctx.data;
		
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		let whereObj = { create_uid: uid };
		
		const cashoutRes = await this.db.collection('usemall-member-money-log').where(whereObj).orderBy("create_time", "desc").get();
		
		response.datas = cashoutRes;
		response.code = 0;
			
		return response;
	}
	
	// 零钱支付
	async pay() {
		let response = {
			code: 1
		};
		
		const {
			order_id,
			pay_code
		} = this.ctx.data;
		
		let uid = '';
		let uname = '';
		const start = Date.now();
		const nowdate = start;
		
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
				uname = userRes.userInfo.nickname || userRes.userInfo.username;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		const ip = this.ctx.context.CLIENTIP;
		const utc8date = this.service.utils.toDateUTC8(Date.now());
		
		if (!order_id) {
			response.msg = `订单ID不存在`;
			return response;
		}
		// 根据订单号获取订单数据
		let orderRes = await this.db.collection('usemall-order')
			.where({
				is_delete: 0,
				order_id: order_id
			})
			.field({
				order_actural_paid: true,
				order_id: true,
				order_type: true,
				order_from: true,
				is_fxs: true,
				order_fxs_uid: true,
				order_fxs_amount: true,
				order_fxs_uid2: true,
				order_fxs_amount2: true,
				order_member_name: true,
				order_member_openid: true,
				order_member_headimg: true,
				order_info: true,
				order_goods_cnt: true,
				create_uid: true,
				create_uname: true,
				state: true,
				order_return_integral: true,
				// 开具发票
				order_invoice_id: true,
				order_invoice: true,
				seckill_id: true,
				group_id: true,
				group_chief_id: true
			})
			.get();
		
		// 订单
		const [order] = orderRes.data;
		if (!(order && order._id)) {
			response.msg = `订单不存在`;
			return response;
		}
		
		if (order.state != '待付款') {
			response.msg = `订单状态：${order.state}`;
			return response;
		}
		
		const moneyRes = await this.db.collection('usemall-member').doc(uid)
			.field({
				member_amount: true
			})
			.get();
		
		const [moneyData] = moneyRes.data;
		
		// 判断当前零钱是否充足
		if (!(moneyData && moneyData.member_amount >= order.order_actural_paid)) {
			response.msg = `剩余零钱不足`;
			return response;
		}
		
		// 订单详情
		const orderDetailRes = await this.db.collection('usemall-order-detail').where({
			order_id: order_id
		}).get();
		if (!(orderDetailRes.data && orderDetailRes.data.length)) {
			response.msg = `订单商品不存在`;
			return response;
		}
		
		// 根据订单号
		// 	1.修改订单状态为 待发货
		// 	2.修改订单支付数据
		// 	3.分销订单写入分销商数据
		// 根据订单获取下单人
		// 根据下单人累计消费金额
		// 根据订单设置,如果为支付成功后扣减库存,则扣减对应商品扣除
		// 修改订单支付数据
		// 写入订单日志
		
		// 拼团订单
		// 判断是否已成团
		// 	未成团
		// 		1. 修改参团表（参团中、几人团、团有效期、团成员）
		// 		2. 修改订单表（待成团）
		// 	已成团
		//		1. 修改参团表（参团中、几人团、团有效期、团成员)
		//		2. 修改订单表（待发货）
		// 拼团表（参团人、参团人数、参团订单数）
		
		let groupData = {};
		let groupChiefData = {};
		let groupMemberIdx = 0;
		if (order.group_id) {
			// false 不验证活动是否已结束或已过期
			groupData = await this.service.marketing.getGroup(order.group_id, false);
			
			if (order.group_chief_id) {
				// 获取参团数据
				groupChiefData = await this.service.marketing.getGroupChief(order.group_chief_id, false);
			} else {
				// 获取订单团购数据
				groupChiefData = await this.service.marketing.getGroupChiefByOrder(order.order_id, false);
			}
			
			if (groupChiefData.state == '已取消') {
				response.msg = `当前拼单活动已取消`;
				return response;
			}
			
			groupMemberIdx = groupChiefData.group_members.findIndex(x => x.order_id == order.order_id);
			if (groupMemberIdx == -1) {
				response.msg = `当前订单未参团`;
				return response;
			}
		}
		
		
		try {
			// 待发货通知
			// 不需要 await，只需发送请求即可
			const messageNotifyUrl = `${uidConfig.config('message-notify.url')}/101`;
			if (messageNotifyUrl.indexOf('http') === 0) {
				uniCloud.httpclient.request(messageNotifyUrl, {
					method: 'post',
					headers: {
						'message-notify-key': uidConfig.config('message-notify.key')
					},
					data: {
						id: order.order_id,
						scene: 101,
						uname: order.order_member_name,
						title: order.group_id ? `拼团订单 ${order.order_id} 已付款` : `订单：${order.order_id} 已付款，请尽快安排发货`,
						type: `${order.order_type} - ${order.order_from} - 零钱支付:￥${order.order_actural_paid / 100}`,
						goods: `${order.order_info}`
					},
					timeout: 30 * 1000,
					contentType: 'json',
					dataType: 'json'
				});
			}
		} catch(e) {
			console.log('message-notify err', e);
		}
		
		
		// 订单配置
		const orderConfig = await this.service.utils.getOrderConfig();
		
		// 开启事务
		const dbtran = await this.db.startTransaction();
		try {
			// 会员已省金额
			let member_economize = 0;
			for (let i = 0; i < orderDetailRes.data.length; i++) {
				let x = orderDetailRes.data[i];
				// 会员已省金额
				member_economize += x.economize_amount;
			}
			
			// 分销订单
			if (order.is_fxs == '是') {
				if (order.order_fxs_uid && order.order_fxs_amount) {
					// 上级
					await dbtran.collection('usemall-distributor').doc(order.order_fxs_uid).update({
						fxs_unsettled_amount: this.db.command.inc(order.order_fxs_amount),
						fxs_order_cnt: this.db.command.inc(1),
						version: this.db.command.inc(1),
						
						last_modify_uid: uid,
						last_modify_uname: '零钱支付',
						last_modify_time: nowdate
					});
								
					await dbtran.collection('usemall-distributor-record').add({
						fxs_uid: order.order_fxs_uid,
						profit_amount: order.order_fxs_amount,
						member_guid: uid,
						member_openid: order.order_member_openid,
						member_name: order.order_member_name,
						member_headimg: order.order_member_headimg,
						order_id: order.order_id,
						source_desc: `下级成员购买[${order.order_info} * ${order.order_goods_cnt}]`,
						source_type: '下单',
						remark: '',
						state: '未结算',
						version: 1,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
					await dbtran.collection('usemall-distributor-log').add({
						fxs_uid: order.order_fxs_uid,
						oper_content: `下级会员下单[+${order.order_fxs_amount / 100}]`,
						oper_type: '下单收益',
						oper_ip: ip,
						remark: `下级会员`,
						version: 1,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
				}
				
				if (order.order_fxs_uid2 && order.order_fxs_amount2) {
					// 上上级
					await dbtran.collection('usemall-distributor').doc(order.order_fxs_uid2).update({
						fxs_unsettled_amount: this.db.command.inc(order.order_fxs_amount2),
						fxs_order_cnt: this.db.command.inc(1),
						version: this.db.command.inc(1),
					
						last_modify_uid: uid,
						last_modify_uname: '零钱支付',
						last_modify_time: nowdate
					});
					
					await dbtran.collection('usemall-distributor-record').add({
						fxs_uid: order.order_fxs_uid2,
						profit_amount: order.order_fxs_amount2,
						member_guid: uid,
						member_openid: order.order_member_openid,
						member_name: order.order_member_name,
						member_headimg: order.order_member_headimg,
						order_id: order.order_id,
						source_desc: `下下级成员购买[${order.order_info} * ${order.order_goods_cnt}]`,
						source_type: '下单',
						remark: '',
						state: '未结算',
						version: 1,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
					await dbtran.collection('usemall-distributor-log').add({
						fxs_uid: order.order_fxs_uid2,
						oper_content: `下下级会员下单[+${order.order_fxs_amount2 / 100}]`,
						oper_type: '下单收益',
						oper_ip: ip,
						remark: `下下级会员`,
						version: 1,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					});
				}
				
				// 记录下单人 分销数据、累计消费、积分、已省金额
				// 修改剩余零钱
				const memberRes = await dbtran.collection('usemall-member').doc(uid).update({
					member_monetary: this.db.command.inc(order.order_actural_paid),
					member_amount: this.db.command.inc(-order.order_actural_paid),
					myfxs_order_cnt: this.db.command.inc(1),
					
					myfxs_profit_amount: this.db.command.inc(order.order_fxs_amount),
					myfxs_profit_amount2: this.db.command.inc(order.order_fxs_amount2),
					
					member_economize: this.db.command.inc(member_economize)
				});
			} else {
				
				// 修改下单人 累计消费、积分、已省金额
				// 修改剩余零钱
				const memberRes = await dbtran.collection('usemall-member').doc(uid).update({
					member_monetary: this.db.command.inc(order.order_actural_paid),
					member_amount: this.db.command.inc(-order.order_actural_paid),
					
					member_economize: this.db.command.inc(member_economize)
				});
			}
			
			const orderUpdateObj = {
				state: '待发货'
			};
			const groupUpdateObj = {};
			const groupMemberUpdateObj = {};
			
			// 拼团订单
			// 判断是否已成团
			// 	待成团
			// 		1. 修改参团表（状态、已付款数）
			// 		2. 修改订单表（待成团）
			// 	已成团
			//		1. 修改参团表（状态、已付款数)
			//		2. 修改订单表（待发货）
			// 拼团表（参团人、参团人数、参团订单数）
			
			// 拼团订单
			if (groupData && groupData._id) {
				// 参团人
				const groupMember = {
					order_id: order.order_id,
					uid: order.create_uid,
					// uname: order.order_member_name,
					uname: '',
					uheadimg: order.order_member_headimg,
					pay_time: nowdate,
					state: '已付款'
				};
				// 已参团人数大于等于团购数量
				if (groupChiefData.group_member_pay_cnt >= groupData.group_num - 1) {
					// 成团时间
					orderUpdateObj.order_group_time = nowdate;
					// 已成团
					orderUpdateObj.state = '待发货';
					groupMemberUpdateObj.state = '已成团';
					
					// 成团数
					groupUpdateObj.group_success_num = this.db.command.inc(1);
				} else {
					// 待成团
					orderUpdateObj.state = '待成团';
					groupMemberUpdateObj.state = '参团中';
				}
				
				if (!order.group_chief_id) {
					// 开团订单有效期
					orderUpdateObj.order_expire_time = Date.now() + groupData.group_time * 60 * 60 * 1000;
					// 修改到期时间
					groupMemberUpdateObj.expire_time = orderUpdateObj.order_expire_time;
				} else {
					// 参团订单有效期
					orderUpdateObj.order_expire_time = groupChiefData.expire_time;
				}
				
				// 修改参团表（状态、已付款数)
				await dbtran.collection('usemall-market-groupbuy-member').doc(groupChiefData._id).update({
					['group_members.' + groupMemberIdx]: {
						state: '已付款'
					},
					group_member_pay_cnt: this.db.command.inc(1),
					...groupMemberUpdateObj
				});
				
				// 插入最新的参团人
				groupData.group_members.unshift(groupMember);
				
				// 拼团表（参团人、参团人数、参团订单数）
				await dbtran.collection('usemall-market-groupbuy').doc(groupData._id).update({
					group_member_cnt: this.db.command.inc(1),
					group_order_cnt: this.db.command.inc(1),
					group_members: groupData.group_members.slice(0, 6),
					
					version: this.db.command.inc(1),
					
					last_modify_uid: uid,
					last_modify_time: nowdate,
					last_modify_uname: '零钱支付',
					
					...groupUpdateObj
				});
			}
			
			
			// 查询当前支付后是否小于0
			const userMoneyRes = await dbtran.collection('usemall-member').doc(uid).field({
				member_amount: true
			}).get();
		
			if (userMoneyRes.data.member_amount < 0) {
				await dbtran.rollback();
				response.msg = '当前可用零钱不足';
				return response;
			}
			
			const logRes = await dbtran.collection('usemall-member-money-log').add({
				user_uid: uid,
				order_id: order_id,
				money: order.order_actural_paid,
				money_fmt: '-' + order.order_actural_paid / 100,
				source: '订单支付',
				type: '支出',
				remark: `订单支付-${order.order_actural_paid / 100}`,
				time: this.service.utils.formatdate(utc8date, 'yyyy-MM-dd hh:mm'),
				ip: ip,
				is_delete: 0,
				create_uid: uid,
				create_time: nowdate
			});
			
			await dbtran.collection('usemall-order-pay').add({
				order_id: order_id,
				pay_openid: '',
				pay_way: '零钱支付',
				pay_state: '已付款',
				version: 1,
				is_delete: 0,
				create_uid: uid,
				create_time: nowdate
			});
			
			// 订单日志
			await dbtran.collection('usemall-order-log').add({
				order_id: order.order_id,
				log_type: '订单支付',
				current_state: orderUpdateObj.state,
				prev_state: '待付款',
				ip: ip,
				is_delete: 0,
				create_uid: uid,
				create_time: nowdate
			});
			
			// 支付后扣减库存
			if (orderConfig.stock_ded_type == 2) { 
				// 扣减库存
				orderUpdateObj.order_ded_stock = 1;
			}
			// 更改订单状态
			await dbtran.collection('usemall-order').doc(order._id).update({
				last_modify_time: nowdate,
				last_modify_uid: uid,
				last_modify_uname: '零钱支付',
				
				version: this.db.command.inc(1),
				
				order_pay_state: '已付款',
				order_pay_way: '零钱支付',
				order_pay_no: logRes.id,
				order_pay_time: nowdate,
				
				...orderUpdateObj
			});
			
			await dbtran.commit();
			response.code = 0;
			
			// 开具发票
			if (order.order_invoice_id) {
				await this.db.collection('usemall-order-invoice').doc(order.order_id).set({
					order_id: order.order_id,
					order_amount: order.order_actural_paid,
					invoice: order.order_invoice,
					invoice_url: '',
					state: 0,
					state_str: '申请中',
					version: 1,
					is_delete: 0,
					create_time: nowdate,
					create_uid: order.create_uid,
					create_uname: order.create_uname,
					last_modify_time: nowdate
				});
			}
			
			// 已成团订单
			if (groupMemberUpdateObj.state == '已成团') {
				const order_ids = [];
				const order_logs = [];
				// 修改对应参团人员订单状态为待发货
				for (let i = 0; i < groupChiefData.group_members.length; i++) {
					// 跳过当前支付的参团人员
					if (i == groupMemberIdx) continue;
					
					let groupMember = groupChiefData.group_members[i]
					
					order_ids.push(groupMember.order_id);
					order_logs.push({
						order_id: groupMember.order_id,
						log_type: '拼单成功',
						current_state: '待发货',
						prev_state: '待成团',
						ip: ip,
						is_delete: 0,
						create_uid: uid,
						create_time: nowdate
					})
				}
				
				// 订单日志
				if (order_logs.length) await this.db.collection('usemall-order-log').add(order_logs);
				
				// 更改订单状态
				await this.db.collection('usemall-order').where({
					order_id: this.db.command.in(order_ids),
					state: '待成团'
				}).update({
					order_group_time: nowdate,
					
					last_modify_time: nowdate,
					last_modify_uid: uid,
					last_modify_uname: '零钱支付',
					
					version: this.db.command.inc(1),
					
					state: '待发货'
				});
			}
			
			// 支付后扣减库存
			if (orderConfig.stock_ded_type == 2) {
				for (let i = 0; i < orderDetailRes.data.length; i++) {
					let x = orderDetailRes.data[i];
					// 扣减库存
					await this.db.collection('usemall-goods')
						.where({
							_id: x.goods_id,
							stock_num: this.db.command.gte(x.goods_num)
						})
						.update({
							stock_num: this.db.command.inc(-x.goods_num),
							sale_cnt: this.db.command.inc(x.goods_num)
						});
					// 扣减SKU库存
					if (x.goods_sku) {
						await this.db.collection('usemall-goods-sku')
							.where({
								goods_id: x.goods_id,
								goods_sku: x.goods_sku,
								stock_num: this.db.command.gte(x.goods_num)
							})
							.update({
								stock_num: this.db.command.inc(-x.goods_num),
								sale_cnt: this.db.command.inc(x.goods_num)
							});
					}
				}
			}
			
		} catch (e) {
			await dbtran.rollback();
			response.msg = e.message;
		}
		
		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
	
}
